package com.example.examsystem.repository;

import com.example.examsystem.model.Category;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * 分类数据访问层
 */
@Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {
    
    /**
     * 根据学科ID统计分类数量
     */
    long countBySubjectId(Long subjectId);
    
    /**
     * 根据学科ID查找分类
     */
    List<Category> findBySubjectId(Long subjectId);
    
    /**
     * 根据学科ID和状态查找分类并按名称排序
     */
    List<Category> findBySubjectIdAndStatusOrderByName(Long subjectId, String status);
    
    /**
     * 根据名称查找分类
     */
    List<Category> findByNameContaining(String name);
    
    /**
     * 根据代码查找分类
     */
    Optional<Category> findByCode(String code);
    
    /**
     * 检查分类代码是否存在
     */
    boolean existsByCode(String code);
    
    /**
     * 检查代码是否存在（排除指定ID）
     */
    boolean existsByCodeAndIdNot(String code, Long id);
    
    /**
     * 检查分类名称是否存在
     */
    boolean existsByNameAndSubjectId(String name, Long subjectId);
    
    /**
     * 检查分类名称是否存在（排除指定ID）
     */
    boolean existsByNameAndSubjectIdAndIdNot(String name, Long subjectId, Long id);
    
    /**
     * 根据状态查找分类并按名称排序
     */
    List<Category> findByStatusOrderByName(String status);
    
    /**
     * 分页查询分类（支持多条件筛选）
     */
    @Query("""
       SELECT c FROM Category c
       WHERE
           (:name IS NULL OR :name = '' OR LOWER(c.name) LIKE LOWER(CONCAT('%', :name, '%'))) AND
           (:code IS NULL OR :code = '' OR LOWER(c.code) LIKE LOWER(CONCAT('%', :code, '%'))) AND
           (:subjectId IS NULL OR c.subjectId = :subjectId) AND
           (:status IS NULL OR :status = '' OR c.status = :status)
       """)
    Page<Category> findByQuery(@Param("name") String name,
                              @Param("code") String code,
                              @Param("subjectId") Long subjectId,
                              @Param("status") String status,
                              Pageable pageable);
}



